#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
响应验证模块 - Response Validator Module

该模块负责验证机器人接口方法的返回值格式，包括：
- 返回值格式验证
- 响应格式装饰器
- 批量方法验证
- 格式标准化工具

This module validates robot interface method return value formats including:
- Return value format validation
- Response format decorator
- Batch method validation
- Format standardization tools
"""

import functools
from typing import Any, Callable, Dict, List, Union


class ResponseValidator:
    """
    响应验证器类
    Response Validator Class
    
    负责验证机器人接口方法的返回值格式
    Validates robot interface method return value formats
    """
    
    def __init__(self, muto_instance=None):
        """
        初始化响应验证器
        Initialize response validator
        
        Args:
            muto_instance: Muto机器人实例 Muto robot instance
        """
        self.muto = muto_instance
    
    # ==================== 返回值格式验证 Return Value Format Validation ====================
    
    def validate_response_format(self, response: Any, method_name: str = "unknown") -> Dict[str, Any]:
        """
        验证单个响应的格式
        Validate format of a single response
        
        Args:
            response: 要验证的响应 Response to validate
            method_name: 方法名称 Method name
            
        Returns:
            dict: 验证结果 Validation result
        """
        validation_result = {
            'method_name': method_name,
            'is_valid': False,
            'format_info': {},
            'issues': []
        }
        
        try:
            # 检查是否为元组
            if not isinstance(response, tuple):
                validation_result['issues'].append(f"返回值不是元组类型，实际类型: {type(response).__name__} Return value is not tuple, actual type: {type(response).__name__}")
                validation_result['format_info']['actual_type'] = type(response).__name__
                return validation_result
            
            # 检查元组长度
            if len(response) != 3:
                validation_result['issues'].append(f"元组长度不正确，期望3个元素，实际{len(response)}个 Tuple length incorrect, expected 3 elements, actual {len(response)}")
                validation_result['format_info']['tuple_length'] = len(response)
                return validation_result
            
            # 检查第一个元素（success: bool）
            if not isinstance(response[0], bool):
                validation_result['issues'].append(f"第一个元素应为bool类型，实际类型: {type(response[0]).__name__} First element should be bool, actual type: {type(response[0]).__name__}")
            
            # 检查第二个元素（message: str）
            if not isinstance(response[1], str):
                validation_result['issues'].append(f"第二个元素应为str类型，实际类型: {type(response[1]).__name__} Second element should be str, actual type: {type(response[1]).__name__}")
            
            # 检查第三个元素（data: dict）
            if not isinstance(response[2], dict):
                validation_result['issues'].append(f"第三个元素应为dict类型，实际类型: {type(response[2]).__name__} Third element should be dict, actual type: {type(response[2]).__name__}")
            
            # 记录格式信息
            validation_result['format_info'] = {
                'tuple_length': len(response),
                'element_types': [type(elem).__name__ for elem in response],
                'success_value': response[0] if len(response) > 0 else None,
                'message_length': len(response[1]) if len(response) > 1 and isinstance(response[1], str) else 0,
                'data_keys': list(response[2].keys()) if len(response) > 2 and isinstance(response[2], dict) else []
            }
            
            # 如果没有问题，标记为有效
            if not validation_result['issues']:
                validation_result['is_valid'] = True
            
            return validation_result
            
        except Exception as e:
            validation_result['issues'].append(f"验证过程中出错 Error during validation: {str(e)}")
            validation_result['format_info']['error'] = str(e)
            return validation_result
    
    def validate_all_responses(self) -> tuple:
        """
        验证所有接口方法的返回值格式
        Validate return value format of all interface methods
        
        Returns:
            tuple: (success, message, validation_report)
        """
        try:
            validation_report = {
                'total_methods': 0,
                'validated_methods': 0,
                'failed_methods': [],
                'method_results': {}
            }
            
            # 获取所有公共方法进行测试
            methods_to_test = [
                ('get_status', lambda: self.muto.get_status()),
                ('print_status', lambda: self.muto.print_status()),
                ('get_attitude', lambda: self.muto.get_attitude()),
                ('get_imu_raw_data', lambda: self.muto.get_imu_raw_data()),
                ('list_saved_positions', lambda: self.muto.list_saved_positions()),
                ('get_camera_status', lambda: self.muto.get_camera_status()),
                ('check_lidar_status', lambda: self.muto.check_lidar_status()),
            ]
            
            validation_report['total_methods'] = len(methods_to_test)
            
            for method_name, method_func in methods_to_test:
                try:
                    result = method_func()
                    
                    # 使用验证方法检查格式
                    validation_result = self.validate_response_format(result, method_name)
                    
                    if validation_result['is_valid']:
                        validation_report['validated_methods'] += 1
                        validation_report['method_results'][method_name] = {
                            'status': 'valid',
                            'format_info': validation_result['format_info']
                        }
                    else:
                        validation_report['failed_methods'].append(method_name)
                        validation_report['method_results'][method_name] = {
                            'status': 'invalid',
                            'issues': validation_result['issues'],
                            'format_info': validation_result['format_info']
                        }
                        
                except Exception as e:
                    validation_report['failed_methods'].append(method_name)
                    validation_report['method_results'][method_name] = {
                        'status': 'error',
                        'error': str(e)
                    }
            
            success_rate = validation_report['validated_methods'] / validation_report['total_methods'] * 100
            
            if validation_report['validated_methods'] == validation_report['total_methods']:
                message = f"所有 {validation_report['total_methods']} 个方法都通过了返回值格式验证 All {validation_report['total_methods']} methods passed return format validation"
                return True, message, validation_report
            else:
                failed_count = len(validation_report['failed_methods'])
                message = f"验证完成，成功率 {success_rate:.1f}% ({validation_report['validated_methods']}/{validation_report['total_methods']})，{failed_count} 个方法格式不正确 Validation completed, success rate {success_rate:.1f}% ({validation_report['validated_methods']}/{validation_report['total_methods']}), {failed_count} methods have incorrect format"
                return False, message, validation_report
                
        except Exception as e:
            return False, f"验证过程中出错 Error during validation: {str(e)}", {}
    
    def test_response_format_decorator(self, test_value: Any = None) -> Any:
        """
        测试响应格式装饰器的方法
        Method to test response format decorator
        
        Args:
            test_value: 测试值 Test value
            
        Returns:
            任意格式的返回值（会被装饰器标准化）
            Any format return value (will be standardized by decorator)
        """
        if test_value is None:
            return True, "测试成功 Test successful", {'test': 'passed'}
        elif isinstance(test_value, bool):
            return test_value
        elif isinstance(test_value, str):
            return True, test_value
        elif isinstance(test_value, dict):
            return test_value
        else:
            return {'result': test_value}
    
    # ==================== 格式标准化工具 Format Standardization Tools ====================
    
    def standardize_response(self, response: Any, default_message: str = "操作完成 Operation completed") -> tuple:
        """
        标准化响应格式
        Standardize response format
        
        Args:
            response: 原始响应 Original response
            default_message: 默认消息 Default message
            
        Returns:
            tuple: 标准化后的响应 Standardized response (success, message, data)
        """
        try:
            # 如果已经是正确格式
            if (isinstance(response, tuple) and len(response) == 3 and
                isinstance(response[0], bool) and isinstance(response[1], str) and isinstance(response[2], dict)):
                return response
            
            # 如果是布尔值
            if isinstance(response, bool):
                return response, default_message, {}
            
            # 如果是字符串
            if isinstance(response, str):
                return True, response, {}
            
            # 如果是字典
            if isinstance(response, dict):
                return True, default_message, response
            
            # 如果是元组但格式不正确
            if isinstance(response, tuple):
                if len(response) == 1:
                    return self.standardize_response(response[0], default_message)
                elif len(response) == 2:
                    if isinstance(response[0], bool) and isinstance(response[1], str):
                        return response[0], response[1], {}
                    elif isinstance(response[0], bool) and isinstance(response[1], dict):
                        return response[0], default_message, response[1]
                    else:
                        return True, str(response[1]), {'data': response[0]}
                else:
                    # 长度超过3，取前3个元素
                    return self.standardize_response(response[:3], default_message)
            
            # 其他类型，包装为数据
            return True, default_message, {'result': response}
            
        except Exception as e:
            return False, f"响应标准化失败 Response standardization failed: {str(e)}", {'original_response': str(response)}
    
    def validate_and_standardize(self, response: Any, method_name: str = "unknown") -> tuple:
        """
        验证并标准化响应
        Validate and standardize response
        
        Args:
            response: 原始响应 Original response
            method_name: 方法名称 Method name
            
        Returns:
            tuple: 标准化后的响应 Standardized response
        """
        try:
            # 先验证格式
            validation_result = self.validate_response_format(response, method_name)
            
            # 如果格式正确，直接返回
            if validation_result['is_valid']:
                return response
            
            # 如果格式不正确，尝试标准化
            standardized = self.standardize_response(response, f"{method_name}执行完成 {method_name} execution completed")
            
            if hasattr(self.muto, 'debug') and self.muto.debug:
                print(f"[DEBUG] 方法 '{method_name}' 的响应已标准化 Response for method '{method_name}' has been standardized")
                print(f"[DEBUG] 原始响应 Original response: {response}")
                print(f"[DEBUG] 标准化后 Standardized: {standardized}")
            
            return standardized
            
        except Exception as e:
            return False, f"验证和标准化失败 Validation and standardization failed: {str(e)}", {'method_name': method_name, 'error': str(e)}


# ==================== 响应格式装饰器 Response Format Decorator ====================

def ensure_response_format(func: Callable) -> Callable:
    """
    确保方法返回标准格式的装饰器
    Decorator to ensure method returns standard format
    
    标准格式: (success: bool, message: str, data: dict)
    Standard format: (success: bool, message: str, data: dict)
    
    Args:
        func: 要装饰的方法 Method to decorate
        
    Returns:
        Callable: 装饰后的方法 Decorated method
    """
    @functools.wraps(func)
    def wrapper(*args, **kwargs) -> tuple:
        try:
            result = func(*args, **kwargs)
            
            # 如果已经是正确格式
            if (isinstance(result, tuple) and len(result) == 3 and
                isinstance(result[0], bool) and isinstance(result[1], str) and isinstance(result[2], dict)):
                return result
            
            # 创建ResponseValidator实例进行标准化
            # 注意：这里假设第一个参数是self，且有muto属性
            if args and hasattr(args[0], 'muto'):
                validator = ResponseValidator(args[0].muto)
                return validator.standardize_response(result, f"{func.__name__}执行完成 {func.__name__} execution completed")
            else:
                # 简单标准化
                if isinstance(result, bool):
                    return result, f"{func.__name__}执行完成 {func.__name__} execution completed", {}
                elif isinstance(result, str):
                    return True, result, {}
                elif isinstance(result, dict):
                    return True, f"{func.__name__}执行完成 {func.__name__} execution completed", result
                elif isinstance(result, tuple):
                    if len(result) == 1:
                        return ensure_response_format(lambda: result[0])()
                    elif len(result) == 2:
                        if isinstance(result[0], bool) and isinstance(result[1], str):
                            return result[0], result[1], {}
                        elif isinstance(result[0], bool) and isinstance(result[1], dict):
                            return result[0], f"{func.__name__}执行完成 {func.__name__} execution completed", result[1]
                        else:
                            return True, str(result[1]), {'data': result[0]}
                    else:
                        return ensure_response_format(lambda: result[:3])()
                else:
                    return True, f"{func.__name__}执行完成 {func.__name__} execution completed", {'result': result}
                    
        except Exception as e:
            return False, f"{func.__name__}执行失败 {func.__name__} execution failed: {str(e)}", {'error': str(e)}
    
    return wrapper


# ==================== 辅助函数 Helper Functions ====================

def validate_response_tuple(response: Any) -> bool:
    """
    快速验证响应是否为标准格式
    Quick validation if response is in standard format
    
    Args:
        response: 要验证的响应 Response to validate
        
    Returns:
        bool: 是否为标准格式 Whether in standard format
    """
    return (isinstance(response, tuple) and len(response) == 3 and
            isinstance(response[0], bool) and isinstance(response[1], str) and isinstance(response[2], dict))


def create_success_response(message: str, data: Dict[str, Any] = None) -> tuple:
    """
    创建成功响应
    Create success response
    
    Args:
        message: 成功消息 Success message
        data: 响应数据 Response data
        
    Returns:
        tuple: 标准格式响应 Standard format response
    """
    return True, message, data or {}


def create_error_response(message: str, data: Dict[str, Any] = None) -> tuple:
    """
    创建错误响应
    Create error response
    
    Args:
        message: 错误消息 Error message
        data: 响应数据 Response data
        
    Returns:
        tuple: 标准格式响应 Standard format response
    """
    return False, message, data or {}


def extract_response_data(response: tuple) -> Dict[str, Any]:
    """
    从标准响应中提取数据部分
    Extract data part from standard response
    
    Args:
        response: 标准格式响应 Standard format response
        
    Returns:
        dict: 数据部分 Data part
    """
    if validate_response_tuple(response):
        return response[2]
    return {}


def is_success_response(response: tuple) -> bool:
    """
    检查响应是否表示成功
    Check if response indicates success
    
    Args:
        response: 标准格式响应 Standard format response
        
    Returns:
        bool: 是否成功 Whether successful
    """
    if validate_response_tuple(response):
        return response[0]
    return False


def get_response_message(response: tuple) -> str:
    """
    从响应中获取消息
    Get message from response
    
    Args:
        response: 标准格式响应 Standard format response
        
    Returns:
        str: 消息内容 Message content
    """
    if validate_response_tuple(response):
        return response[1]
    return "未知响应格式 Unknown response format"